package com.bizmda.bizsip.sink.connector;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import com.bizmda.bizsip.common.BizException;
import com.bizmda.bizsip.common.BizResultEnum;
import com.bizmda.bizsip.config.AbstractSinkConfig;
import com.bizmda.bizsip.config.SinkConfigMapping;
import com.bizmda.bizsip.sink.connector.sinkbean.JSONObjectSinkBeanInterface;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;

@Slf4j
public class Connector {
    private AbstractSinkConnector sinkConnector;
    private boolean isJsonObject;
    public static Connector getSinkConnector(String sinkId) {
        Connector connector = new Connector();
        SinkConfigMapping sinkConfigMapping = SpringUtil.getBean("sinkConfigMapping");
        AbstractSinkConfig sinkConfig = sinkConfigMapping.getSinkConfig(sinkId);
        try {
            if (sinkConfig == null) {
                throw new BizException(BizResultEnum.SINK_NOT_SET, "sinkId[" + sinkId + "]在sink.yml中没有配置");
            }
            if (sinkConfig.getConnectorMap() == null) {
                connector.sinkConnector = null;
                return connector;
            }
            String connectorType = (String) sinkConfig.getConnectorMap().get("type");

            Class<Object> clazz = (Class) AbstractSinkConnector.CONNECTOR_TYPE_MAP.get(connectorType);
            if (clazz == null) {
                throw new BizException(BizResultEnum.CONNECTOR_NOT_SET);
            }

            try {
                connector.sinkConnector = (AbstractSinkConnector) clazz.getDeclaredConstructor().newInstance();
                connector.sinkConnector.setType(connectorType);
            } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                throw new BizException(BizResultEnum.CONNECTOR_JAVA_CLASS_CREATE_ERROR, e);
            }

            connector.sinkConnector.init(sinkConfig);
            connector.isJsonObject = false;
            if ((connector.sinkConnector instanceof BeanSinkConnector)) {
                connector.isJsonObject = true;
            } else if (connector.sinkConnector instanceof SinkBeanSinkConnector) {
                if (((SinkBeanSinkConnector) connector.sinkConnector).getSinkBean() instanceof JSONObjectSinkBeanInterface) {
                    connector.isJsonObject = true;
                }
            }
        } catch (BizException e) {
            log.error("getSinkConnector("+sinkId+")出错!",e);
            return null;
        }
        return connector;
    }

    public AbstractSinkConnector getSinkConnector() {
        return this.sinkConnector;
    }

//    public Object process(JSONObject beforeJsonObject, Object packMessage) throws BizException {
//        return this.sinkConnector.process(beforeJsonObject,packMessage);
//    }

    public byte[] process(byte[] packMessage) throws BizException {
        if (isJsonObject) {
            throw new BizException(BizResultEnum.CONNECTOR_IN_PARAMETER_TYPE_ERROR,"传入byte[],但要求是JSONObject类型!");
        }
        return (byte[])this.sinkConnector.process(packMessage);
    }

    public JSONObject process(JSONObject packMessage) throws BizException {
        if (!isJsonObject) {
            throw new BizException(BizResultEnum.CONNECTOR_IN_PARAMETER_TYPE_ERROR,"传入JSONObject,但要求是byte[]类型!");
        }
        return (JSONObject) this.sinkConnector.process(packMessage);
    }
}
